package com.niit.gams.config;

import com.niit.gams.pojo.SysResource;
import com.niit.gams.pojo.SysRole;
import com.niit.gams.pojo.SysUser;
import com.niit.gams.service.SysResourceService;
import com.niit.gams.service.SysRoleService;
import com.niit.gams.service.SysUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class UserRealm extends AuthorizingRealm {
  @Autowired
  private SysUserService sysUserService;

  @Autowired
  private SysRoleService sysRoleService;
  @Autowired
  private SysResourceService sysResourceService;

  /*
   *  授权
   *
   */
  @Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
    System.out.println("执行了=>授权doGetAuthorizationInfo");
    //验证方法doGetAuthenticationInfo()传递的第一个参数
    SysUser user = (SysUser) principalCollection.getPrimaryPrincipal();
    //查找该用户所有的角色
    List<SysRole> roles = sysRoleService.findRolesByUserId(user.getId());

    //权限信息对象,用来存放用户的所有的角色（role）及权限（permission）
    SimpleAuthorizationInfo authorInfo = new SimpleAuthorizationInfo();
    if (!roles.isEmpty()) {
      //获取所有角色名称
      Set<String> roleNames = roles.stream().map(r -> r.getName()).collect(Collectors.toSet());
      //角色id
      List<Long> rids = new ArrayList<>();
      for (SysRole role : roles) {
        rids.add(role.getId());
      }
      //对应角色的所有权限
      List<SysResource> resources = sysResourceService.findResourcesInRoleId(rids);
      Set<String> permissions = resources.stream().map(r -> r.getPermission()).collect(Collectors.toSet());

      authorInfo.setRoles(roleNames);
      authorInfo.setStringPermissions(permissions);
    }
    return authorInfo;
  }

  /*
   * 认证
   */
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    System.out.println("执行了=>认证doGetAuthorizationInfo");

    UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
    SysUser user = sysUserService.findUserByName(token.getUsername());
    if (user == null) {
      throw new UnknownAccountException("账号不存在！");
    }
    if (user.getStatus() != null && "0".equals(user.getStatus())) {
      throw new LockedAccountException("帐号已被锁定，禁止登录！");
    }
    //必须设置user参数，上面的getPrimaryPrincipal()才能获取
    return new SimpleAuthenticationInfo(user, user.getPassword(), "");
  }
}